// 请求工具类
import axios from 'axios'
import store from '@/store'
import router from '@/router'
import to from 'await-to-js'
import { refreshTokenAPI } from '@/api/user'

export const baseURL = 'http://geek.itheima.net/'
// 1. 创建新的axios实例
const instance = axios.create({
  baseURL,
  timeout: 5000
})

// 3. 请求头带token
instance.interceptors.request.use(config => {
  // 对config进行修改
  const token = store.state.user.token
  if (token) config.headers.Authorization = `Bearer ${token}`
  return config
}, err => Promise.reject(err))

// 4. token失效处理
instance.interceptors.response.use(res => res, async err => {
  // 1. 判断状态码401
  // 2. 删除token
  // 3. 跳转登录，当前路由的完整地址需要传递给登录页面。因为：将来登录完事需要回跳
  if (err.response && err.response.status === 401) {
    // ★1. 使用refresh_token更新token不能使用instance，请求拦截器中会覆盖请求头
    const [err2, res] = await to(refreshTokenAPI(store.state.user.refreshToken))
    // ★2. 刷新token失败
    if (err2) {
      store.commit('user/setToken', '')
      // 组件：this.$route.path 路径  fullPath 完整路径，带参数的
      // 通过 router实例 获取当前路由信息对象 currentRoute
      // 回跳地址：/order?id=100&name=tom  ===> 跳转登录地址  /login?returnUrl=/order?id=100&name=tom
      // 地址可能回出现特殊字符 & 需要转换成url编码 encodeURIComponent
      // 转义后 /login?returnUrl=%2Forder%3Fid%3D100%26name%3Dtom
      router.push('/login?returnUrl=' + encodeURIComponent(router.currentRoute.fullPath))
    } else {
      // ★3. 刷新token成功
      store.commit('user/setToken', res.data.data.token)
      // ★4. 继续发送失败的请求，需要成功
      // err.config 是之前失败的请求配置
      return instance(err.config)
    }
  }
  return Promise.reject(err)
})

// 2. 导出一个通过新axios实例调用接口的函数
export default ({ url, method = 'get', params, data, headers }) => {
  // 封装函数：可以在调用的时候做额外的事情
  // instance 就是axios，传入的对象就是配置选项，返回值是promise对象
  const promise = instance({ url, method, params, data, headers })
  return to(promise)

  // 参考代码
  // return new Promise((resolve, reject) => {
  //   promise.then(res => {
  //     resolve([null, res])
  //   }).catch(err => {
  //     resolve([err, null])
  //   })
  // })
}
